package com.xhsj.user.lsm.service;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xhsj.user.hr.system.service.TbGlobalUserService;
import com.xhsj.user.lsm.entity.*;
import com.xhsj.user.lsm.mapper.TbBadgesProcessOpinionMapper;
import com.xhsj.user.lsm.mapper.TbBadgesProcessTaskMapper;
import com.xhsj.user.lsm.mapper.TbContractOpinionFileMapper;
import com.xhsj.user.sms.base.BaseService;
import com.xhsj.user.utils.IdGen;
import com.xhsj.user.utils.StringUtils;
import com.xhsj.user.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * 任务表 服务实现类
 * </p>
 *
 * @author suxiaolin
 * @since 2020-03-16
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
//@CacheConfig(cacheNames = "TbBadgesProcessTask")
public class TbBadgesProcessTaskService extends BaseService<TbBadgesProcessTaskMapper, TbBadgesProcessTask> {
    @Autowired
    private TbBadgesProcessTaskMapper dao;
    @Autowired
    private TbGlobalUserService tbGlobalUserService;

    @Autowired
    private TbBadgesProcessNodeService tbBadgesProcessNodeService;

    @Autowired
    private TbBadgesProcessHiTaskService tbBadgesProcessHiTaskService;

    @Autowired
    private TbBadgesProcessOpinionService tbBadgesProcessOpinionService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private TbBadgesProcessOpinionMapper tbBadgesProcessOpinionMapper;

    @Autowired
    private TbContractOpinionFileMapper tbContractOpinionFileMapper;

    //角色名称 综合管理部
    @Value("${rolekeyname.integratedManager}")
    private String integratedManager;

    //角色名称 商务经理
    @Value("${rolekeyname.roleBusinessName}")
    private String roleBusinessName;



    /**
     * 启动流程
     *
     * @author 苏小林
     * @date 2020/3/17 9:51
     * @param: entity
     * @return: boolean
     */
    public String startProcess(Map<String, Object> map) throws Exception {
        Object createBy = map.get("createBy");
        Object dataId = map.get("dataId");
        Object type = map.get("type");
        String nodeName = "";

        try {
            // 领导
            String leader = StringUtils.getStringValue(map,"userId");

            // 综合管理部
            Object roleIds = map.get("roleIds");
            // 查询初始流程节点
            TbBadgesProcessNode firstNode = tbBadgesProcessNodeService.getFirstNode(StringUtils.toInteger(type), 0);
            if(StringUtils.isNotBlank(roleIds)){
                // 获取下一个节点
                String nextNodeId1 = firstNode.getNextNodeId();
                // 查询下一节点
                Map<String, Object> map1 = getNextNode(nextNodeId1, 0, StringUtils.toInteger(type));
                firstNode.setNodeId(firstNode.getNodeId());
                firstNode.setNextNodeId(String.valueOf(map1.get("next_node_id")));
            }

            // 创建人历史任务
            TbBadgesProcessHiTask cjrTbBadgesProcessHiTask = new TbBadgesProcessHiTask(String.valueOf(createBy), String.valueOf(dataId), firstNode.getNodeId(), 0, String.valueOf(createBy));
            boolean cjrSave = tbBadgesProcessHiTaskService.save(cjrTbBadgesProcessHiTask);

            Thread.sleep(1000);

            if(StringUtils.isNotBlank(roleIds) && roleIds instanceof List<?>){
                for (Object roleId:(List<?>) roleIds) {
                    // 主管审核 任务
                    TbBadgesProcessTask tbBadgesProcessTask = new TbBadgesProcessTask("", String.valueOf(roleId), "", String.valueOf(dataId), firstNode.getNextNodeId(), String.valueOf(createBy), String.valueOf(createBy));
                    if(!this.save(tbBadgesProcessTask))
                        throw new Exception("启动流程失败");
                    // 主管审核历史任务
                    TbBadgesProcessHiTask tbBadgesProcessHiTask = new TbBadgesProcessHiTask("", String.valueOf(dataId), firstNode.getNextNodeId(), 2, String.valueOf(createBy));
                    if(!tbBadgesProcessHiTaskService.save(tbBadgesProcessHiTask))
                        throw new Exception("启动流程失败");
                }
            }else if((!"291".equals(leader) && "1".equals(String.valueOf(type)) ||  "2".equals(String.valueOf(type)))){
                TbBadgesProcessTask tbBadgesProcessTask = new TbBadgesProcessTask(leader, "", "", String.valueOf(dataId), firstNode.getNextNodeId(), String.valueOf(createBy), String.valueOf(createBy));
                if(!this.save(tbBadgesProcessTask))
                    throw new Exception("启动流程失败");
                // 主管审核历史任务
                TbBadgesProcessHiTask tbBadgesProcessHiTask = new TbBadgesProcessHiTask(leader, String.valueOf(dataId), firstNode.getNextNodeId(), 2, String.valueOf(createBy));
                if(!tbBadgesProcessHiTaskService.save(tbBadgesProcessHiTask))
                throw new Exception("启动流程失败");
            }


            if (cjrSave) {
                String nextNodeId = firstNode.getNextNodeId();

                Map<String, Object> nextNode = getNextNode(nextNodeId, 0,StringUtils.toInteger(type));

                nodeName = String.valueOf(nextNode.get("node_name"));
            } else {
                log.error("启动流程失败,任务启动过程中有返回结果为0的");
                throw new Exception("启动流程失败");
            }

        } catch (Exception e) {
            log.error("启动流程出错:{}", e);
            throw e;
        }

        return nodeName;


    }

    /**
     * 查询正在运行的任务列表
     * @author 苏小林
     * @date 2020/3/17 11:38
     * @param: data
     * @return: com.baomidou.mybatisplus.core.metadata.IPage<com.xhsj.user.lsm.entity.TbBadgesProcessTask>
     */
//    public IPage<TaskModel> findRunTaskList(Map<String, Object> data) {
//        int currentPage=1;
//        if (!Objects.isNull(data.get("page"))) {
//            currentPage=(Integer) data.get("page");
//        }
//        int pageSize=20;
//        if (!Objects.isNull(data.get("size"))) {
//            pageSize=(Integer) data.get("size");
//        }
//        String userId = String.valueOf(data.get("userId"));
//
//        List<String> roleList = tbGlobalUserService.getRoleListByUserId(Long.parseLong(userId));
//
//        Page<TaskModel> page = new Page(currentPage,pageSize);
//        IPage<TaskModel> iPage = dao.findRunTaskList(page,userId,roleList);
//        return iPage;
//
//    }

    /**
     * 查询历史任务列表
     * @author 苏小林
     * @date 2020/3/17 11:38
     * @param: data
     * @return: com.baomidou.mybatisplus.core.metadata.IPage<com.xhsj.user.lsm.entity.TbBadgesProcessTask>
     */
//    public IPage<TaskModel> findHiTaskList(Map<String, Object> data) {
//        int currentPage=1;
//        if (!Objects.isNull(data.get("page"))) {
//            currentPage=(Integer) data.get("page");
//        }
//        int pageSize=20;
//        if (!Objects.isNull(data.get("size"))) {
//            pageSize=(Integer) data.get("size");
//        }
//        String userId = String.valueOf(data.get("userId"));
//
//        Integer status = StringUtils.toInteger(data.get("status"));
//        if (status == 0) {// 查询全部
//            status = null;
//        }
//
//        IPage<TaskModel> page = new Page(currentPage, pageSize);
//
//        IPage<TaskModel> iPage = dao.findHiTaskList(page,userId,status);
//        return iPage;
//
//    }

    /**
     * 处理审核
     *
     * @author 苏小林
     * @date 2020/3/17 14:05
     * @param: data
     * @return: boolean
     */

    public String handleAudit(Map<String, Object> data) throws Exception {

        String nodeName = "";
        // 数据id
        String dataId = String.valueOf(data.get("dataId"));
        // 下一个节点审核用户id
        Object userId = data.get("userId");
        Object type = data.get("type");
        // 下一个节点审核用户角色
        Object roleIds = data.get("roleIds");
        // 登录用户id
        String createBy = String.valueOf(data.get("createBy"));
        // 节点id
        String nodeId = String.valueOf(data.get("nodeId"));
        // 审核意见
        Object opinionText = data.get("opinionText");
        // 流程申请用户id
        String proposerId = String.valueOf(data.get("proposerId"));
        // 状态
        Integer status = StringUtils.toInteger(data.get("status"));// 对应节点表
        //时间
        Date currentDate=new Date();
        // 中deal_with字段 0 通过 1 退回 2 重要
        try {
            // 查询下一节点
            Map<String, Object> map = getNextNode(nodeId, status, StringUtils.toInteger(type));
            Object nextNodeId = map.get("next_node_id");

            //查询下一个节点的下一个节点名称
            String id = String.valueOf(map.get("nextId"));
            TbBadgesProcessNode nextNode = tbBadgesProcessNodeService.getById(id);
            if (!Objects.isNull(nextNodeId) && StringUtils.isNotBlank(nextNodeId)) {
                if (!Objects.isNull(userId)) {
                    List<String> split = JSONArray.parseArray(String.valueOf(userId), String.class);
                    for (String s : split) {
                        // 添加下一个节点执行任务
                        TbBadgesProcessTask tbBadgesProcessTask = new TbBadgesProcessTask(s, "", "", dataId, String.valueOf(nextNodeId), createBy, proposerId);
                        if(StringUtils.isBlank(tbBadgesProcessTask.getId())) {
                            tbBadgesProcessTask.setCreateDate(currentDate);
                        }
                        tbBadgesProcessTask.setUpdateDate(currentDate);
                        boolean saveTask = this.save(tbBadgesProcessTask);
                        if (!saveTask) {
                            log.error("保存数据失败");
                            throw new Exception("保存数据失败");
                        }

                        TbBadgesProcessHiTask tbBadgesProcessHiTask = new TbBadgesProcessHiTask(s, dataId, String.valueOf(nextNodeId), 2, proposerId);
                        if(StringUtils.isBlank(tbBadgesProcessHiTask.getId())) {
                            tbBadgesProcessHiTask.setCreateDate(currentDate);
                        }
                        tbBadgesProcessHiTask.setUpdateDate(currentDate);
                        boolean saveHiTask = tbBadgesProcessHiTaskService.save(tbBadgesProcessHiTask);
                        if (!saveHiTask) {
                            log.error("保存数据失败");
                            throw new Exception("保存数据失败");
                        }
                    }
                }

                // 角色
                if (!Objects.isNull(roleIds)) {
                    List<String> split1 = JSONArray.parseArray(String.valueOf(roleIds), String.class);
                    for (String s : split1) {
                        // 添加正在执行任务
                        TbBadgesProcessTask tbBadgesProcessTask = new TbBadgesProcessTask("", s, "", dataId, String.valueOf(nextNodeId), createBy, proposerId);
                        if(StringUtils.isBlank(tbBadgesProcessTask.getId())) {
                            tbBadgesProcessTask.setCreateDate(currentDate);
                        }
                        tbBadgesProcessTask.setUpdateDate(currentDate);
                        boolean saveTask = this.save(tbBadgesProcessTask);
                        if (!saveTask) {
                            log.error("保存数据失败");
                            throw new Exception("保存数据失败");
                        }

                        TbBadgesProcessHiTask tbBadgesProcessHiTask = new TbBadgesProcessHiTask("", dataId, String.valueOf(nextNodeId), 2, proposerId);
                        if(StringUtils.isBlank(tbBadgesProcessHiTask.getId())) {
                            tbBadgesProcessHiTask.setCreateDate(currentDate);
                        }
                        tbBadgesProcessHiTask.setUpdateDate(currentDate);
                        boolean saveHiTask = tbBadgesProcessHiTaskService.save(tbBadgesProcessHiTask);
                        if (!saveHiTask) {
                            log.error("保存数据失败");
                            throw new Exception("保存数据失败");
                        }
                    }
                }
            }

            // 修改目前执行的任务
            TbBadgesProcessHiTask tbBadgesProcessHiTask = new TbBadgesProcessHiTask();
            tbBadgesProcessHiTask.setUserId(createBy);
            tbBadgesProcessHiTask.setDataId(dataId);
            tbBadgesProcessHiTask.setNodeId(nodeId);
            tbBadgesProcessHiTask.setCreateBy(createBy);
            tbBadgesProcessHiTask.setUpdateBy(createBy);
            tbBadgesProcessHiTask.setUpdateDate(currentDate);
            tbBadgesProcessHiTask.setStatus(0);// 审核通过
            if (status == 1) {
                tbBadgesProcessHiTask.setStatus(1);// 审核退回
            }
            int row = tbBadgesProcessHiTaskService.updateHiTask(tbBadgesProcessHiTask);
            if (row == 0) {
                log.error("修改数据失败");
                throw new Exception("修改数据失败");
            }

            int row1 = dao.deleteTask(dataId, nodeId);
            if (row1 == 0) {
                log.error("删除数据失败");
                throw new Exception("删除数据失败");
            }

            if (StringUtils.isNotBlank(opinionText)) {
                data.put("currentDate",currentDate);
                execProcessOpinion(data);
//                TbBadgesProcessOpinion tbBadgesProcessOpinion = new TbBadgesProcessOpinion();
//                tbBadgesProcessOpinion.setNodeId(nodeId);
//                tbBadgesProcessOpinion.setOpinionText(String.valueOf(opinionText));
//                tbBadgesProcessOpinion.setDataId(dataId);
//                tbBadgesProcessOpinion.setCreateBy(createBy);
//
//                boolean save = tbBadgesProcessOpinionService.save(tbBadgesProcessOpinion);
//                if (!save) {
//                    log.error("保存意见数据失败");
//                    throw new Exception("保存意见数据失败");
//                }
            }

            nodeName = nextNode.getNodeName();
        } catch (Exception e) {
            log.error("添加流程失败", e);
            throw new Exception(e);
        }
        return nodeName;
    }


    //审批意见及附件
    public Boolean execProcessOpinion(Map<String,Object> data) throws Exception {
        // 审批意见 先删除后增加
        TbBadgesProcessOpinion processOpinion = new TbBadgesProcessOpinion();
        processOpinion.setOpinionText(String.valueOf(data.get("opinionText")));
        if (StringUtils.isNotBlank(processOpinion)) {
            if (StringUtils.isNotBlank(processOpinion.getId())) {
                //删除意见
                if (!tbBadgesProcessOpinionService.removeById(String.valueOf(processOpinion.getId()))) {
                    log.error("删除意见数据失败");
                    throw new Exception("删除意见数据失败");
                }
                //删除意见相关的附件
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq("opinion_id", processOpinion.getId());
                if (!tbBadgesProcessOpinionService.remove(wrapper)) {
                    log.error("删除意见附件数据失败");
                    throw new Exception("删除意见附件数据失败");
                }
            }
            Date date= (Date) data.get("currentDate");
            processOpinion.setId(IdGen.uuid());
            processOpinion.setDataId(String.valueOf(data.get("dataId")));
            processOpinion.setNodeId(String.valueOf(data.get("nodeId")));
            processOpinion.setCreateBy(String.valueOf(data.get("createBy")));
            processOpinion.setUpdateBy(String.valueOf(data.get("createBy")));
            processOpinion.setCreateDate(date);
            processOpinion.setUpdateDate(date);
            int insert = tbBadgesProcessOpinionMapper.insert(processOpinion);
            if (insert != 1) {
                log.error("意见数据失败");
                throw new Exception("保存意见数据失败");
            }

            //意见附件 先删除后增加
            List<Map<String,Object>> tbPurchaseProcessOpinionFileList = (List<Map<String, Object>>) data.get("contractOpinionFile");
            if (tbPurchaseProcessOpinionFileList != null) {
                for (Map<String,Object> processOpinionFile : tbPurchaseProcessOpinionFileList
                ) {
                    TbContractOpinionFile opinionFile= StringUtils.toJavaBean(processOpinionFile,TbContractOpinionFile.class);
                    opinionFile.setId(IdGen.uuid());
                    opinionFile.setOpinionId(processOpinion.getId());
                    opinionFile.setCreateBy(String.valueOf(data.get("createBy")));
                    opinionFile.setUpdateBy(String.valueOf(data.get("createBy")));
                    opinionFile.setUpdateDate(date);
                    int insert1 = tbContractOpinionFileMapper.insert(opinionFile);
                    if (insert1 != 1) {
                        log.error("保存意见附件数据失败");
                        throw new Exception("保存意见附件数据失败");
                    }
                }
            }
        }
        return true;
    }

    //下一个节点名称
    private Map<String, Object> getNodeName(String nodeId) {
        return dao.getNodeName(nodeId);
    }

    /**
     * 获取下一个节点
     *
     * @author 苏小林
     * @date 2020/3/19 13:47
     * @param: nodeId
     * @param: status
     * @return: java.util.Map<java.lang.String   ,   java.lang.Object>
     */
    private Map<String, Object> getNextNode(String nodeId, Integer status, Integer type) {
//        QueryWrapper queryWrapper = new QueryWrapper();
//        queryWrapper.select("id","next_node_id","node_name","audit_role","audit_user");
//        queryWrapper.eq("node_id",nodeId);
//        queryWrapper.eq("deal_with",status);
//        return tbBadgesProcessNodeService.getMap(queryWrapper);
        return tbBadgesProcessNodeService.getNextNodeId(nodeId, status, type);
    }


    public boolean delByDataId(String id) {
        Integer result = dao.delByDataId(id);
        return null != result && result >= 0;
    }
}
